package com.basic.common.core.service.impl;

import com.basic.common.annotation.DataScope;
import com.basic.common.core.mapper.BaseMapper;
import com.basic.common.core.service.IBaseService;
import com.basic.common.utils.ClassUtils;
import com.basic.common.utils.DateUtils;
import com.basic.common.utils.SecurityUtils;
import com.basic.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 基础服务业务接口实现类，提供数据操作的基本方法。
 *
 * @param <Mapper> 继承自BaseMapper的特定Mapper类型
 * @param <T> 泛型实体类型
 * @author zhaoxy_jn@163.com
 */
public abstract class BaseServiceImpl<Mapper extends BaseMapper<T>, T> implements IBaseService<T> {

    private static final Logger logger = LoggerFactory.getLogger(BaseServiceImpl.class);

    @Autowired
    private Mapper baseMapper;

    /**
     * 插入实体对象，自动设置创建相关信息。
     *
     * @param po 待插入的实体对象
     * @return 影响的行数
     */
    @Override
    public int insert(T po){
        try {
            setFieldValue(po, "createBy",1);
            setFieldValue(po, "createTime",1);
            setFieldValue(po, "deptId",1);
            setFieldValue(po, "userId",1);
        } catch (IllegalAccessException | NoSuchFieldException e) {
            logger.error("Error setting field values for insert: {}", e.getMessage());
        }
        return baseMapper.insert(po);
    }

    /**
     * 更新实体对象，自动设置更新相关信息。
     *
     * @param po 待更新的实体对象
     * @return 影响的行数
     */
    @Override
    public int update(T po) {
        try {
            setFieldValue(po, "updateBy",2);
            setFieldValue(po, "updateTime",2);
        } catch (IllegalAccessException | NoSuchFieldException e) {
            logger.error("Error setting field values for update: {}", e.getMessage());
        }
        return baseMapper.update(po);
    }

    /**
     * 根据ID删除实体。
     *
     * @param id 实体的ID
     * @return 影响的行数
     */
    @Override
    public int delete(Object id) {
        return baseMapper.delete(id);
    }

    /**
     * 根据ID数组批量删除实体。
     *
     * @param ids 实体ID的数组
     * @return 影响的行数
     */
    @Override
    public int deleteByIds(Object[] ids) {
        return baseMapper.deleteByIds(ids);
    }

    /**
     * 根据ID获取实体对象。
     *
     * @param id 实体的ID
     * @return 实体对象
     */
    @Override
    public T get(Object id) {
        return (T) baseMapper.get(id);
    }

    /**
     * 获取实体对象列表，应用数据范围注解限制查询结果。
     *
     * @param po 实体对象，用于构建查询条件
     * @return 实体对象列表
     */
    @Override
    @DataScope(deptAlias = "t", userAlias = "t")
    public List<T> getList(T po) {
        return baseMapper.getList(po);
    }

    private void setFieldValue(Object target, String fieldName,int type) throws IllegalAccessException, NoSuchFieldException {
        Field field = ClassUtils.getField(target.getClass(), fieldName);
        if (field != null) {
            field.setAccessible(true);
            if (StringUtils.equals("createBy",field.getName()) && StringUtils.isNull(field.get(target)) && type == 1){
                field.set(target, SecurityUtils.getUsername());
            }
            if (StringUtils.equals("createTime",field.getName()) && StringUtils.isNull(field.get(target)) && type == 1){
                field.set(target, DateUtils.getNowDate());
            }
            if (StringUtils.equals("userId",field.getName()) && StringUtils.isNull(field.get(target)) && type == 1){
                field.set(target, SecurityUtils.getUserId());
            }
            if (StringUtils.equals("deptId",field.getName()) && StringUtils.isNull(field.get(target)) && type == 1){
                field.set(target, SecurityUtils.getDeptId());
            }
            if (StringUtils.equals("updateBy",field.getName()) && StringUtils.isNull(field.get(target)) && type == 2){
                field.set(target, SecurityUtils.getUsername());
            }
            if (StringUtils.equals("updateTime",field.getName()) && StringUtils.isNull(field.get(target)) && type == 2){
                field.set(target, DateUtils.getNowDate());
            }
        } else {
            logger.warn("Field not found: {}", fieldName);
        }
    }

}
